<template>
  <div
    ref="floatDrag"
    class="float-position"
    :class="{ hideBall: hideBall }"
    :style="{ left: left + 'px', top: top + 'px', zIndex: zIndex }"
    @touchmove.prevent
    @mousemove.prevent
    @mousedown="mouseDown"
    @mouseup="mouseUp"
    @dblclick="toggleVisible"
  >
    <div class="closeBtn" @click="toggleBall">
      <svg
        t="1702523888711"
        class="icon"
        viewBox="0 0 1024 1024"
        version="1.1"
        xmlns="http://www.w3.org/2000/svg"
        p-id="5934"
        width="16"
        height="16"
      >
        <path
          d="M782.426059 824.924989l-584.588225-584.727395c-11.987009-11.990079-11.984962-31.42778 0.005116-43.414789 11.990079-11.987009 31.42778-11.984962 43.414789 0.005117l584.588225 584.727395c11.987009 11.990079 11.984962 31.42778-0.005116 43.414788-11.989055 11.988032-31.42778 11.984962-43.414789-0.005116z"
          fill=""
          p-id="5935"
        ></path>
        <path
          d="M197.768249 824.856427c-11.987009-11.990079-11.984962-31.42778 0.005117-43.414788l584.727394-584.589249c11.990079-11.987009 31.42778-11.984962 43.414789 0.005117 11.987009 11.990079 11.984962 31.42778-0.005116 43.414788l-584.727395 584.589249c-11.990079 11.987009-31.42778 11.984962-43.414789-0.005117z"
          fill=""
          p-id="5936"
        ></path>
      </svg>
    </div>
    <svg
      t="1702534579597"
      class="icon"
      viewBox="0 0 1024 1024"
      version="1.1"
      xmlns="http://www.w3.org/2000/svg"
      p-id="9939"
      id="mx_n_1702534579598"
      width="200"
      height="200"
    >
      <path
        d="M554.688 500.352v256H469.312v-256h-128L512 314.24l170.688 186.24h-128zM1024 640.192C1024 782.912 919.872 896 787.648 896h-512C123.904 896 0 761.6 0 597.504 0 451.968 94.656 331.52 226.432 302.976 284.16 195.456 391.808 128 512 128c152.32 0 282.112 108.416 323.392 261.12C941.888 413.44 1024 519.04 1024 640.192z m-259.2-205.312c-24.448-129.024-128.896-222.72-252.8-222.72-97.28 0-183.04 57.344-224.64 147.456l-9.28 20.224-20.928 2.944c-103.36 14.4-178.368 104.32-178.368 214.72 0 117.952 88.832 214.4 196.928 214.4h512c88.32 0 157.504-75.136 157.504-171.712 0-88.064-65.92-164.928-144.96-171.776l-29.504-2.56-5.888-30.976z"
        fill="#ffffff"
        p-id="9940"
      ></path>
    </svg>
    <uploadFile
      :fileVisible.sync="fileVisible"
      :updateLoading="updateLoading"
    ></uploadFile>
    <div class="wave" v-if="loading">
      <!-- <p class="progress">{{progress}}%</p> -->
    </div>
  </div>
</template>

<script>
import UploadFile from "./uploadFile.vue";
import { EventBus } from "@/components/javaScript/EventBus";

export default {
  name: "UploadBall",
  props: {
    distanceRight: {
      type: Number,
      default: 0,
    },
    distanceBottom: {
      type: Number,
      default: 100,
    },
    isScrollHidden: {
      type: Boolean,
      default: false,
    },
    isCanDraggable: {
      type: Boolean,
      default: true,
    },
    zIndex: {
      type: Number,
      default: 9990,
    },
    value: {
      type: String,
      default: "悬浮球！",
    },
  },

  components: {
    UploadFile,
  },

  //data 域
  data() {
    return {
      clientWidth: null,
      clientHeight: null,
      left: 0,
      top: 0,
      timer: null,
      currentTop: 0,
      mousedownX: 0,
      mousedownY: 0,
      fileVisible: false,
      hideBall: false,
      loading: false,
    };
  },
  created() {
    this.clientWidth = document.documentElement.clientWidth;
    this.clientHeight = document.documentElement.clientHeight;
  },
  mounted() {
    this.isCanDraggable &&
      this.$nextTick(() => {
        this.floatDrag = this.$refs.floatDrag;
        // 获取元素位置属性
        this.floatDragDom = this.floatDrag.getBoundingClientRect();
        // 设置初始位置
        this.left =
          this.clientWidth - this.floatDragDom.width - this.distanceRight;
        this.top =
          this.clientHeight - this.floatDragDom.height - this.distanceBottom;
        this.initDraggable();
      });
    this.isScrollHidden && window.addEventListener("scroll", this.handleScroll);
    window.addEventListener("resize", this.handleResize);
    this.initUpload();
  },
  methods: {
    updateLoading(data) {
      this.loading = data;
    },
    toggleBall(e) {
      e.stopPropagation();
      this.hideBall = true;
    },
    toggleVisible() {
      this.fileVisible = !this.fileVisible;
    },
    /**
     * 设置滚动监听
     * 设置滚动时隐藏悬浮按钮，停止时显示
     */
    handleScroll() {
      this.timer && clearTimeout(this.timer);
      this.timer = setTimeout(() => {
        this.handleScrollEnd();
      }, 200);
      this.currentTop =
        document.documentElement.scrollTop || document.body.scrollTop;
      if (this.left > this.clientWidth / 2) {
        // 判断元素位置再左侧还是右侧
        this.left = this.clientWidth + this.floatDragDom.width;
      } else {
        this.left = -this.floatDragDom.width;
      }
    },
    /**
     * 滚动结束
     */
    handleScrollEnd() {
      let scrollTop =
        document.documentElement.scrollTop || document.body.scrollTop;
      if (scrollTop === this.currentTop) {
        if (this.left > this.clientWidth / 2) {
          // 判断元素位置再左侧还是右侧
          this.left = this.clientWidth - this.floatDragDom.width;
        } else {
          this.left = 0;
        }
        clearTimeout(this.timer);
      }
    },
    /**
     * 窗口resize监听
     */
    handleResize() {
      this.clientWidth = document.documentElement.clientWidth;
      this.clientHeight = document.documentElement.clientHeight;
      this.checkDraggablePosition();
    },
    /**
     * 初始化draggable
     */
    initDraggable() {
      this.floatDrag.addEventListener("touchstart", this.toucheStart);
      this.floatDrag.addEventListener("touchmove", (e) => this.touchMove(e));
      this.floatDrag.addEventListener("touchend", this.touchEnd);
    },
    mouseDown(e) {
      const event = e || window.event;
      this.mousedownX = event.screenX;
      this.mousedownY = event.screenY;
      const that = this;
      let floatDragWidth = this.floatDragDom.width / 2;
      let floatDragHeight = this.floatDragDom.height / 2;
      if (event.preventDefault) {
        event.preventDefault();
      }
      this.canClick = false;
      this.floatDrag.style.transition = "none";
      document.onmousemove = function (e) {
        var event = e || window.event;
        that.left = event.clientX - floatDragWidth;
        that.top = event.clientY - floatDragHeight;
        if (that.left < 0) that.left = 0;
        if (that.top < 0) that.top = 0;
        if (that.left >= that.clientWidth - floatDragWidth * 2) {
          that.left = that.clientWidth - floatDragWidth * 2;
        }
        if (that.top >= that.clientHeight - floatDragHeight * 2) {
          that.top = that.clientHeight - floatDragHeight * 2;
        }
      };
    },
    mouseUp(e) {
      const event = e || window.event;
      //判断只是单纯的点击，没有拖拽
      if (
        this.mousedownY == event.screenY &&
        this.mousedownX == event.screenX
      ) {
        this.$emit("handlepaly");
      }
      document.onmousemove = null;
      this.checkDraggablePosition();
      this.floatDrag.style.transition = "all 0.3s";
    },
    toucheStart() {
      this.canClick = false;
      this.floatDrag.style.transition = "none";
    },
    touchMove(e) {
      this.canClick = true;
      if (e.targetTouches.length === 1) {
        // 单指拖动
        let touch = event.targetTouches[0];
        this.left = touch.clientX - this.floatDragDom.width / 2;
        this.top = touch.clientY - this.floatDragDom.height / 2;
      }
    },
    touchEnd() {
      if (!this.canClick) return; // 解决点击事件和touch事件冲突的问题
      this.floatDrag.style.transition = "all 0.3s";
      this.checkDraggablePosition();
    },
    /**
     * 判断元素显示位置
     * 在窗口改变和move end时调用
     */
    checkDraggablePosition() {
      if (this.left + this.floatDragDom.width / 2 >= this.clientWidth / 2) {
        // 判断位置是往左往右滑动
        this.left = this.clientWidth - this.floatDragDom.width;
      } else {
        this.left = 0;
      }
      if (this.top < 0) {
        // 判断是否超出屏幕上沿
        this.top = 0;
      }
      if (this.top + this.floatDragDom.height >= this.clientHeight) {
        // 判断是否超出屏幕下沿
        this.top = this.clientHeight - this.floatDragDom.height;
      }
    },
    initUpload() {
      EventBus.$off("upload");
      EventBus.$on("upload", (data) => {
        this.fileVisible = true;
        this.hideBall = false;
      });
    },
  },
  beforeDestroy() {
    EventBus.$off("upload");
    window.removeEventListener("scroll", this.handleScroll);
    window.removeEventListener("resize", this.handleResize);
  },
};
</script>
<style>
html,
body {
  overflow: hidden;
}
</style>
<style scoped lang="scss">
.float-position {
  position: absolute;
  z-index: 10003;
  right: 0;
  top: 70%;
  width: 60px;
  height: 60px;
  background: deepskyblue;
  border-radius: 50%;
  box-shadow: 0px 0px 10px 2px skyblue;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px;
  user-select: none;
  box-sizing: border-box;
  cursor: pointer;
  &.hideBall {
    display: none;
  }
  &:hover {
    .closeBtn {
      display: block;
    }
  }
}
.closeBtn {
  position: absolute;
  display: none;
  right: -5px;
  top: -10px;
}
.cart {
  border-radius: 50%;
  width: 5em;
  height: 5em;
  display: flex;
  align-items: center;
  justify-content: center;
}
.header-notice {
  display: inline-block;
  transition: all 0.3s;
  span {
    vertical-align: initial;
  }
  .notice-badge {
    color: inherit;
    .header-notice-icon {
      font-size: 16px;
      padding: 4px;
    }
  }
}
.drag-ball .drag-content {
  overflow-wrap: break-word;
  font-size: 14px;
  color: #fff;
  letter-spacing: 2px;
}

.container {
  position: absolute;
  width: 200px;
  height: 200px;
  padding: 5px;
  border: 5px solid rgb(118, 218, 255);
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  overflow: hidden;
}
.wave {
  position: absolute;
  left: 0;
  top: 0;
  width: 60px;
  height: 60px;
  background-color: rgb(118, 218, 255);
  border-radius: 50%;
  z-index: 1;
  overflow: hidden;
}
.wave::before {
  content: "";
  position: absolute;
  width: 120px;
  height: 120px;
  top: 0;
  left: 50%;
  background-color: rgba(255, 255, 255, 0.4);
  border-radius: 42%;
  transform: translate(-50%, -70%) rotate(0);
  animation: rotate 6s linear infinite;
  z-index: 1;
}
.wave::after {
  content: "";
  position: absolute;
  width: 120px;
  height: 120px;
  top: 0;
  left: 50%;
  background-color: rgba(255, 255, 255, 0.4);
  border-radius: 45%;
  transform: translate(-50%, -70%) rotate(0);
  animation: rotate 6s linear infinite;
  z-index: 1;
}
.wave::after {
  border-radius: 47%;
  background-color: rgba(255, 255, 255, 0.9);
  transform: translate(-50%, -70%) rotate(0);
  animation: rotate 10s linear -5s infinite;
  z-index: 2;
}

.progress {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  text-align: center;
  font-size: 18px;
  color: #000;
  z-index: 10;
}

@keyframes rotate {
  50% {
    transform: translate(-50%, -75%) rotate(180deg);
  }
  100% {
    transform: translate(-50%, -70%) rotate(360deg);
  }
}
</style>

